Reorganize coverage report for set session description 
diff --git a/webrtc/RTCPeerConnection-onnegotiationneeded.html b/webrtc/RTCPeerConnection-onnegotiationneeded.html index 6d0fe6f..fb9fcbf 100644 --- a/webrtc/RTCPeerConnection-onnegotiationneeded.html +++ b/webrtc/RTCPeerConnection-onnegotiationneeded.html 
@@ -7,7 +7,7 @@  'use strict';    // Test is based on the following editor draft: - // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html    /* Helper Functions */   @@ -212,15 +212,13 @@  }, 'negotiationneeded event should not fire if signaling state is not stable');    /* - 4.3.1. RTCPeerConnection Operation - To set an RTCSessionDescription description - 10. If connection's signaling state is now stable, update the - negotiation-needed flag. If connection's [[needNegotiation]] slot - was true both before and after this update, queue a task that runs - the following steps: - 1. If connection's [[isClosed]] slot is true, abort these steps. - 2. If connection's [[needNegotiation]] slot is false, abort these steps. - 3. Fire a simple event named negotiationneeded at connection. + 4.3.1.6. Set the RTCSessionSessionDescription + 2.2.10. If connection's signaling state is now stable, update the negotiation-needed + flag. If connection's [[NegotiationNeeded]] slot was true both before and after + this update, queue a task that runs the following steps: + 1. If connection's [[IsClosed]] slot is true, abort these steps. + 2. If connection's [[NegotiationNeeded]] slot is false, abort these steps. + 3. Fire a simple event named negotiationneeded at connection.  */  promise_test(t => {  const pc = new RTCPeerConnection(); 
diff --git a/webrtc/RTCPeerConnection-ontrack.html b/webrtc/RTCPeerConnection-ontrack.html new file mode 100644 index 0000000..22e9d28 --- /dev/null +++ b/webrtc/RTCPeerConnection-ontrack.html 
@@ -0,0 +1,49 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCPeerConnection.prototype.ontrack</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + 'use strict'; + + // tests that ontrack is called and parses the msid information from the SDP and creates + // the streams with matching identifiers. + async_test(t => { + const pc = new RTCPeerConnection(); + + // Fail the test if the ontrack event handler is not implemented + assert_own_property(pc, 'ontrack', 'Expect pc to have ontrack event handler attribute'); + + const sdp = `v=0 +o=- 166855176514521964 2 IN IP4 127.0.0.1 +s=- +t=0 0 +a=msid-semantic:WMS * +m=audio 9 UDP/TLS/RTP/SAVPF 111 +c=IN IP4 0.0.0.0 +a=rtcp:9 IN IP4 0.0.0.0 +a=ice-ufrag:someufrag +a=ice-pwd:somelongpwdwithenoughrandomness +a=fingerprint:sha-256 8C:71:B3:8D:A5:38:FD:8F:A4:2E:A2:65:6C:86:52:BC:E0:6E:94:F2:9F:7C:4D:B5:DF:AF:AA:6F:44:90:8D:F4 +a=setup:actpass +a=rtcp-mux +a=mid:mid1 +a=sendonly +a=rtpmap:111 opus/48000/2 +a=msid:stream1 track1 +a=ssrc:1001 cname:some +`; + + pc.ontrack = t.step_func(event => { + assert_equals(event.streams.length, 1, 'the track belongs to one MediaStream'); + assert_equals(event.streams[0].id, 'stream1', 'the stream name is parsed from the MSID line'); + t.done(); + }); + + pc.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp})) + .catch(t.step_func(err => { + assert_unreached('Error ' + err.name + ': ' + err.message); + })); + }, 'setRemoteDescription should trigger ontrack event when the MSID of the stream is is parsed.'); + +</script> 
diff --git a/webrtc/RTCPeerConnection-setLocalDescription.html b/webrtc/RTCPeerConnection-setLocalDescription.html index be8ae58..d86cc78 100644 --- a/webrtc/RTCPeerConnection-setLocalDescription.html +++ b/webrtc/RTCPeerConnection-setLocalDescription.html 
@@ -8,28 +8,80 @@  'use strict';    // Test is based on the following editor draft: - // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html    // The following helper functions are called from RTCPeerConnection-helper.js: - // generateOffer() - // generateAnswer() - // assert_session_desc_not_equals() - // assert_session_desc_equals() - // test_state_change_event() - // test_never_resolve() - + // generateOffer + // generateAnswer + // assert_session_desc_not_equals + // assert_session_desc_equals + // test_state_change_event + // test_never_resolve    /* - * 4.3.2. setLocalDescription(offer) + 4.3.2. Interface Definition + [Constructor(optional RTCConfiguration configuration)] + interface RTCPeerConnection : EventTarget { + Promise<void> setRemoteDescription( + RTCSessionDescriptionInit description); + + readonly attribute RTCSessionDescription? remoteDescription; + readonly attribute RTCSessionDescription? currentRemoteDescription; + readonly attribute RTCSessionDescription? pendingRemoteDescription; + ... + }; + + 4.6.2. RTCSessionDescription Class + dictionary RTCSessionDescriptionInit { + required RTCSdpType type; + DOMString sdp = ""; + }; + + 4.6.1. RTCSdpType + enum RTCSdpType { + "offer", + "pranswer", + "answer", + "rollback" + };  */    /* - * 5. If description.sdp is null and description.type is offer, set description.sdp - * to lastOffer. + 4.4.2. setLocalDescription + 2. Let lastOffer be the result returned by the last call to createOffer. + 5. If description.sdp is null and description.type is offer, set description.sdp + to lastOffer. + + 4.3.1.6. Set the RTCSessionSessionDescription + 2.2. If description is set as a local description, then run one of the following + steps: + - If description is of type "offer", set connection.pendingLocalDescription + to description and signaling state to have-local-offer.  */  promise_test(t => {  const pc = new RTCPeerConnection(); - return pc.createOffer() + test_state_change_event(t, pc, ['have-local-offer']); + + return pc.createOffer({ offerToReceiveAudio: true }) + .then(offer => + pc.setLocalDescription(offer) + .then(() => { + assert_equals(pc.signalingState, 'have-local-offer'); + assert_session_desc_equals(pc.localDescription, offer); + assert_session_desc_equals(pc.pendingLocalDescription, offer); + assert_equals(pc.currentLocalDescription, null); + })); + }, 'setLocalDescription with valid offer should succeed'); + + /* + 4.4.2. setLocalDescription + 2. Let lastOffer be the result returned by the last call to createOffer. + 5. If description.sdp is null and description.type is offer, set description.sdp + to lastOffer. + */ + promise_test(t => { + const pc = new RTCPeerConnection(); + return pc.createOffer({ offerToReceiveAudio: true })  .then(offer =>  pc.setLocalDescription({ type: 'offer' })  .then(() => { @@ -41,9 +93,11 @@  }, 'setLocalDescription with type offer and null sdp should use lastOffer generated from createOffer');    /* - * 6. If description.type is offer and description.sdp does not match lastOffer, - * reject the promise with a newly created InvalidModificationError and abort - * these steps. + 4.4.2. setLocalDescription + 2. Let lastOffer be the result returned by the last call to createOffer. + 6. If description.type is offer and description.sdp does not match lastOffer, + reject the promise with a newly created InvalidModificationError and abort + these steps.  */  promise_test(t => {  const pc = new RTCPeerConnection(); @@ -54,11 +108,6 @@  pc.setLocalDescription(offer)));  }, 'setLocalDescription() with offer not created by own createOffer() should reject with InvalidModificationError');   - /* - * 6. If description.type is offer and description.sdp does not match lastOffer, - * reject the promise with a newly created InvalidModificationError and abort - * these steps. - */  promise_test(t => {  // Create first offer with audio line, then second offer with  // both audio and video line. Since the second offer is the @@ -97,6 +146,10 @@  }))));  }, 'Creating and setting offer multiple times should succeed');   + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 2.2.1. If connection's [[IsClosed]] slot is true, then abort these steps. + */  test_never_resolve(t => {  const pc = new RTCPeerConnection();   @@ -108,20 +161,24 @@  });  }, 'setLocalDescription(offer) should never resolve if connection is closed in parallel')   - /* - * TODO - * 4.3.1. Setting an RTCSessionDescription - * 2.2.2. If description is set as a local description, then run one of - * the following steps: - * - If description is of type "rollback", then this is a rollback. Set - * connection.pendingLocalDescription to null and signaling state to stable. - * - If description is of type "pranswer", then set connection.pendingLocalDescription - * to description and signaling state to have-local-pranswer. - */ - -  /* setLocalDescription(answer) */   + + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 2. If description is set as a local description, then run one of the following + steps: + + - If description is of type "answer", then this completes an offer answer + negotiation. + + Set connection's currentLocalDescription to description and + currentRemoteDescription to the value of pendingRemoteDescription. + + Set both pendingRemoteDescription and pendingLocalDescription to null. + + Finally set connection's signaling state to stable. + */  promise_test(t => {  const pc = new RTCPeerConnection();  test_state_change_event(t, pc, ['have-remote-offer', 'stable']); @@ -145,6 +202,12 @@  })));  }, 'setLocalDescription() with valid answer should succeed');   + /* + 4.4.2. setLocalDescription + 3. Let lastAnswer be the result returned by the last call to createAnswer. + 4. If description.sdp is null and description.type is answer, set description.sdp + to lastAnswer. + */  promise_test(t => {  const pc = new RTCPeerConnection();   @@ -167,6 +230,13 @@  })));  }, 'setLocalDescription() with type answer and null sdp should use lastAnswer generated from createAnswer');   + /* + 4.4.2. setLocalDescription + 3. Let lastAnswer be the result returned by the last call to createAnswer. + 7. If description.type is answer and description.sdp does not match lastAnswer, + reject the promise with a newly created InvalidModificationError and abort these + steps. + */  promise_test(t => {  const pc = new RTCPeerConnection();   @@ -179,10 +249,7 @@  pc.setLocalDescription(answer))));  }, 'setLocalDescription() with answer not created by own createAnswer() should reject with InvalidModificationError');   - /* - * Operations after returning to stable state - */ - + /* Operations after returning to stable state */  promise_test(t => {  const pc = new RTCPeerConnection();  test_state_change_event(t, pc, ['have-local-offer', 'stable', 'have-local-offer']); @@ -230,16 +297,14 @@  }, 'Switching role from answerer to offerer after going back to stable state should succeed');    /* - * InvalidStateError - * [webrtc-pc] 4.3.1. Setting the RTCSessionDescription - * 2.3. If the description's type is invalid for the current signaling state - * of connection, then reject p with a newly created InvalidStateError - * and abort these steps. - */ + 4.3.1.6. Set the RTCSessionSessionDescription + 2.3. If the description's type is invalid for the current signaling state of + connection, then reject p with a newly created InvalidStateError and abort + these steps.   - /* - * [jsep] 5.5. If the type is "pranswer" or "answer", the PeerConnection - * state MUST be either "have-remote-offer" or "have-local-pranswer". + [jsep] + 5.5. If the type is "pranswer" or "answer", the PeerConnection + state MUST be either "have-remote-offer" or "have-local-pranswer".  */  promise_test(t => {  const pc = new RTCPeerConnection(); @@ -251,10 +316,6 @@    }, 'Calling setLocalDescription(answer) from stable state should reject with InvalidStateError');   - /* - * [jsep] 5.5. If the type is "pranswer" or "answer", the PeerConnection - * state MUST be either "have-remote-offer" or "have-local-pranswer". - */  promise_test(t => {  const pc = new RTCPeerConnection();   @@ -267,4 +328,14 @@  pc.setLocalDescription(answer)));  }, 'Calling setLocalDescription(answer) from have-local-offer state should reject with InvalidStateError');   + /* + TODO + 4.4.2. setLocalDescription + 4. If description.sdp is null and description.type is pranswer, set description.sdp + to lastAnswer. + 7. If description.type is pranswer and description.sdp does not match lastAnswer, + reject the promise with a newly created InvalidModificationError and abort these + steps. + */ +  </script> 
diff --git a/webrtc/RTCPeerConnection-setRemoteDescription.html b/webrtc/RTCPeerConnection-setRemoteDescription.html index da1f488..50a719d 100644 --- a/webrtc/RTCPeerConnection-setRemoteDescription.html +++ b/webrtc/RTCPeerConnection-setRemoteDescription.html 
@@ -8,7 +8,7 @@  'use strict';    // Test is based on the following editor draft: - // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html    // The following helper functions are called from RTCPeerConnection-helper.js:  // generateOffer() @@ -19,9 +19,40 @@  // test_never_resolve()    /* - * 4.3.2. setRemoteDescription(offer) + 4.3.2. Interface Definition + [Constructor(optional RTCConfiguration configuration)] + interface RTCPeerConnection : EventTarget { + Promise<void> setRemoteDescription( + RTCSessionDescriptionInit description); + + readonly attribute RTCSessionDescription? remoteDescription; + readonly attribute RTCSessionDescription? currentRemoteDescription; + readonly attribute RTCSessionDescription? pendingRemoteDescription; + ... + }; + + 4.6.2. RTCSessionDescription Class + dictionary RTCSessionDescriptionInit { + required RTCSdpType type; + DOMString sdp = ""; + }; + + 4.6.1. RTCSdpType + enum RTCSdpType { + "offer", + "pranswer", + "answer", + "rollback" + };  */   + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 2.2.3. Otherwise, if description is set as a remote description, then run one of + the following steps: + - If description is of type "offer", set connection.pendingRemoteDescription + attribute to description and signaling state to have-remote-offer. + */  promise_test(t => {  const pc = new RTCPeerConnection();   @@ -58,6 +89,10 @@  }));  }, 'Setting remote description multiple times with different offer should succeed');   + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 2.2.1. If connection's [[IsClosed]] slot is true, then abort these steps. + */  test_never_resolve(t => {  const pc = new RTCPeerConnection();   @@ -70,11 +105,11 @@  }, 'setRemoteDescription(offer) should never resolve if connection is closed in parallel')    /* - * 4.3.1. Setting an RTCSessionDescription - * 2.4. If the content of description is not valid SDP syntax, then reject p - * with an RTCError (with errorDetail set to "sdp-syntax-error" and the - * sdpLineNumber attribute set to the line number in the SDP where the - * syntax error was detected) and abort these steps. + 4.3.1.6. Set the RTCSessionSessionDescription + 2.1.4. If the content of description is not valid SDP syntax, then reject p with + an RTCError (with errorDetail set to "sdp-syntax-error" and the + sdpLineNumber attribute set to the line number in the SDP where the syntax + error was detected) and abort these steps.  */  promise_test(t => {  const pc = new RTCPeerConnection(); @@ -95,7 +130,7 @@  }, 'setRemoteDescription(offer) with invalid SDP should reject with RTCError');    /* - * 4.6.1. enum RTCSdpType + 4.6.1. enum RTCSdpType  */  promise_test(t => {  const pc = new RTCPeerConnection(); @@ -119,25 +154,22 @@  }));  }, 'setRemoteDescription() with invalid SDP and stable state should reject with InvalidStateError')   - /* - * TODO - * Setting an RTCSessionDescription - * 2.1.5. If the content of description is invalid, then reject p with - * a newly created InvalidAccessError and abort these steps. - * 2.2.5-10 - * setRemoteDescription(rollback) - * setRemoteDescription(pranswer) - * - * Non-testable - * Setting an RTCSessionDescription - * 6. For all other errors, for example if description cannot be - * applied at the media layer, reject p with a newly created OperationError. - */ + /* setRemoteDescription(answer) */    /* - * 4.3.2. setRemoteDescription(answer) - */ + 4.3.1.6. Set the RTCSessionSessionDescription + 2.2.3. Otherwise, if description is set as a remote description, then run one of + the following steps: + - If description is of type "answer", then this completes an offer answer + negotiation.   + Set connection's currentRemoteDescription to description and + currentLocalDescription to the value of pendingLocalDescription. + + Set both pendingRemoteDescription and pendingLocalDescription to null. + + Finally setconnection's signaling state to stable. + */  promise_test(t => {  const pc = new RTCPeerConnection();  test_state_change_event(t, pc, ['have-local-offer', 'stable']); @@ -149,6 +181,8 @@  .then(answer =>  pc.setRemoteDescription(answer)  .then(() => { + assert_equals(pc.signalingState, 'stable'); +  assert_session_desc_equals(pc.localDescription, offer);  assert_session_desc_equals(pc.remoteDescription, answer);   @@ -160,28 +194,7 @@  })));  }, 'setRemoteDescription() with valid state and answer should succeed');   - /* - * TODO - * 4.3.2 setRemoteDescription - * If an a=identity attribute is present in the session description, - * the browser validates the identity assertion. - * - * If the "peerIdentity" configuration is applied to the RTCPeerConnection, - * this establishes a target peer identity of the provided value. Alternatively, - * if the RTCPeerConnection has previously authenticated the identity of the - * peer (that is, there is a current value for peerIdentity ), then this also - * establishes a target peer identity. - * - * The target peer identity cannot be changed once set. Once set, - * if a different value is provided, the user agent must reject - * the returned promise with a newly created InvalidModificationError - * and abort this operation. The RTCPeerConnection must be closed if - * the validated peer identity does not match the target peer identity. - */ - - /* - * Operations after returning to stable state - */ + /* Operations after returning to stable state */    promise_test(t => {  const pc = new RTCPeerConnection(); @@ -231,16 +244,14 @@  }, 'Switching role from offerer to answerer after going back to stable state should succeed');    /* - * InvalidStateError - * [webrtc-pc] 4.3.1. Setting the RTCSessionDescription - * 2.3. If the description's type is invalid for the current signaling state - * of connection, then reject p with a newly created InvalidStateError - * and abort these steps. - */ + 4.3.1.6. Set the RTCSessionSessionDescription + 2.1.3. If the description's type is invalid for the current signaling state of + connection, then reject p with a newly created InvalidStateError and abort + these steps.   - /* - * [jsep] 5.6. If the type is "pranswer" or "answer", the PeerConnection - * state MUST be either "have-local-offer" or "have-remote-pranswer". + [JSEP] + 5.6. If the type is "answer", the PeerConnection state MUST be either + "have-local-offer" or "have-remote-pranswer".  */  promise_test(t => {  const pc = new RTCPeerConnection(); @@ -251,26 +262,6 @@  pc.setRemoteDescription({ type: 'answer', sdp: offer.sdp })));  }, 'Calling setRemoteDescription(answer) from stable state should reject with InvalidStateError');   - - /* - * [jsep] 5.6. If the type is "offer", the PeerConnection state - * MUST be either "stable" or "have-remote-offer". - */ - promise_test(t => { - const pc = new RTCPeerConnection(); - - return pc.createOffer() - .then(offer => pc.setLocalDescription(offer)) - .then(() => generateOffer()) - .then(offer => - promise_rejects(t, 'InvalidStateError', - pc.setRemoteDescription(offer))); - }, 'Calling setRemoteDescription(offer) from have-local-offer state should reject with InvalidStateError'); - - /* - * [jsep] 5.6. If the type is "pranswer" or "answer", the PeerConnection - * state MUST be either "have-local-offer" or "have-remote-pranswer". - */  promise_test(t => {  const pc = new RTCPeerConnection();   @@ -284,44 +275,32 @@    }, 'Calling setRemoteDescription(answer) from have-remote-offer state should reject with InvalidStateError');   - // tests that ontrack is called and parses the msid information from the SDP and creates - // the streams with matching identifiers. - async_test(t => { + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 2.1.3. If the description's type is invalid for the current signaling state of + connection, then reject p with a newly created InvalidStateError and abort + these steps. + + [JSEP] + 5.6. If the type is "offer", the PeerConnection state MUST be either "stable" or + "have-remote-offer". + */ + promise_test(t => {  const pc = new RTCPeerConnection();   - // Fail the test if the ontrack event handler is not implemented - assert_own_property(pc, 'ontrack', 'Expect pc to have ontrack event handler attribute'); + return pc.createOffer() + .then(offer => pc.setLocalDescription(offer)) + .then(() => generateOffer()) + .then(offer => + promise_rejects(t, 'InvalidStateError', + pc.setRemoteDescription(offer))); + }, 'Calling setRemoteDescription(offer) from have-local-offer state should reject with InvalidStateError');   - const sdp = `v=0 -o=- 166855176514521964 2 IN IP4 127.0.0.1 -s=- -t=0 0 -a=msid-semantic:WMS * -m=audio 9 UDP/TLS/RTP/SAVPF 111 -c=IN IP4 0.0.0.0 -a=rtcp:9 IN IP4 0.0.0.0 -a=ice-ufrag:someufrag -a=ice-pwd:somelongpwdwithenoughrandomness -a=fingerprint:sha-256 8C:71:B3:8D:A5:38:FD:8F:A4:2E:A2:65:6C:86:52:BC:E0:6E:94:F2:9F:7C:4D:B5:DF:AF:AA:6F:44:90:8D:F4 -a=setup:actpass -a=rtcp-mux -a=mid:mid1 -a=sendonly -a=rtpmap:111 opus/48000/2 -a=msid:stream1 track1 -a=ssrc:1001 cname:some -`; - - pc.ontrack = t.step_func(event => { - assert_equals(event.streams.length, 1, 'the track belongs to one MediaStream'); - assert_equals(event.streams[0].id, 'stream1', 'the stream name is parsed from the MSID line'); - t.done(); - }); - - pc.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp})) - .catch(t.step_func(err => { - assert_unreached('Error ' + err.name + ': ' + err.message); - })); - }, 'setRemoteDescription should trigger ontrack event when the MSID of the stream is is parsed.'); + /* + TODO + 4.3.2. setRemoteDescription + - If an a=identity attribute is present in the session description, the browser + validates the identity assertion. + */    </script> 
diff --git a/webrtc/RTCSctpTransport-constructor.html b/webrtc/RTCSctpTransport-constructor.html index f840f1e..16b11e3 100644 --- a/webrtc/RTCSctpTransport-constructor.html +++ b/webrtc/RTCSctpTransport-constructor.html 
@@ -8,7 +8,7 @@  'use strict';    // Test is based on the following editor draft: - // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html    // The following helper functions are called from RTCPeerConnection-helper.js:  // generateOffer() @@ -27,18 +27,16 @@  readonly attribute unsigned long maxMessageSize;  };   - 4.3.1. Operation - When the RTCPeerConnection() constructor is invoked - 8. Let connection have an [[sctpTransport]] internal slot, - initialized to null. + 4.4.1.1. Constructor + 8. Let connection have an [[sctpTransport]] internal slot, initialized to null.   - To set an RTCSessionDescription description - 6. If description is of type "answer" or "pranswer", then run the - following steps: - 1. If description initiates the establishment of a new SCTP - association, as defined in [SCTP-SDP], Sections 10.3 and 10.4, - set the value of connection's [[sctpTransport]] internal slot - to a newly created RTCSctpTransport. + 4.3.1.6. Set the RTCSessionSessionDescription + 2.2.6. If description is of type "answer" or "pranswer", then run the + following steps: + 1. If description initiates the establishment of a new SCTP association, + as defined in [SCTP-SDP], Sections 10.3 and 10.4, set the value of + connection's [[SctpTransport]] internal slot to a newly created + RTCSctpTransport.  */    promise_test(t => { 
diff --git a/webrtc/coverage/set-session-description.txt b/webrtc/coverage/set-session-description.txt new file mode 100644 index 0000000..af06967 --- /dev/null +++ b/webrtc/coverage/set-session-description.txt 
@@ -0,0 +1,242 @@ +Coverage Report is based on the following editor draft: +https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html + +4.4.1.6 Set the RTCSessionSessionDescription + + [Trivial] + 1. Let p be a new promise. + + [Trivial] + 2. In parallel, start the process to apply description as described in [JSEP] + (section 5.5. and section 5.6.). + + [Trivial] + 1. If the process to apply description fails for any reason, then user agent + MUST queue a task that runs the following steps: + + [RTCPeerConnection-setLocalDescription] + [RTCPeerConnection-setRemoteDescription] + 1. If connection's [[IsClosed]] slot is true, then abort these steps. + + [RTCPeerConnection-setLocalDescription] + [RTCPeerConnection-setRemoteDescription] + 2. If the description's type is invalid for the current signaling state of + connection as described in [JSEP] (section 5.5. and section 5.6.), then + reject p with a newly created InvalidStateError and abort these steps. + + [RTCPeerConnection-setLocalDescription] + [RTCPeerConnection-setRemoteDescription] + 3. If the content of description is not valid SDP syntax, then reject p + with an RTCError (with errorDetail set to "sdp-syntax-error" and the + sdpLineNumber attribute set to the line number in the SDP where the + syntax error was detected) and abort these steps. + + [Untestable] + 4. If the content of description is invalid, then reject p with a newly + created InvalidAccessError and abort these steps. + + [Untestable] + 5. If the content of description is invalid, then reject p with a newly + created InvalidAccessError and abort these steps. + + [Untestable] + 6. For all other errors, for example if description cannot be applied at + the media layer, reject p with a newly created OperationError. + + [Trivial] + 2. If description is applied successfully, the user agent MUST queue a task + that runs the following steps: + + [RTCPeerConnection-setLocalDescription] + [RTCPeerConnection-setRemoteDescription] + 1. If connection's [[isClosed]] slot is true, then abort these steps. + + [RTCPeerConnection-setLocalDescription] + 2. If description is set as a local description, then run one of the + following steps: + + [RTCPeerConnection-setLocalDescription] + - If description is of type "offer", set connection.pendingLocalDescription + to description and signaling state to have-local-offer. + + [RTCPeerConnection-setLocalDescription] + - If description is of type "answer", then this completes an offer answer + negotiation. + + Set connection's currentLocalDescription to description and + currentRemoteDescription to the value of pendingRemoteDescription. + + Set both pendingRemoteDescription and pendingLocalDescription to null. + Finally set connection's signaling state to stable + + [TODO setLocalDescription] + - If description is of type "rollback", then this is a rollback. Set + connection.pendingLocalDescription to null and signaling state to stable. + + [TODO setLocalDescription] + - If description is of type "pranswer", then set + connection.pendingLocalDescription to description and signaling state to + have-local-pranswer. + + [RTCPeerConnection-setRemoteDescription] + 3. Otherwise, if description is set as a remote description, then run one of the + following steps: + + [RTCPeerConnection-setRemoteDescription] + - If description is of type "offer", set connection.pendingRemoteDescription + attribute to description and signaling state to have-remote-offer. + + [RTCPeerConnection-setRemoteDescription] + - If description is of type "answer", then this completes an offer answer + negotiation. + + Set connection's currentRemoteDescription to description and + currentLocalDescription to the value of pendingLocalDescription. + + Set both pendingRemoteDescription and pendingLocalDescription to null. + + Finally setconnection's signaling state to stable + + [TODO setRemoteDescription] + - If description is of type "rollback", then this is a rollback. + Set connection.pendingRemoteDescription to null and signaling state to stable. + + [TODO setRemoteDescription] + - If description is of type "pranswer", then set + connection.pendingRemoteDescription to description and signaling state + to have-remote-pranswer. + + [RTCPeerConnection-setLocalDescription] + [RTCPeerConnection-setRemoteDescription] + 4. If connection's signaling state changed above, fire a simple event named + signalingstatechange at connection. + + [TODO] + 5. If description is of type "answer", and it initiates the closure of an existing + SCTP association, as defined in [SCTP-SDP], Sections 10.3 and 10.4, set the value + of connection's [[sctpTransport]] internal slot to null. + + [RTCSctpTransport] + 6. If description is of type "answer" or "pranswer", then run the following steps: + + [RTCSctpTransport] + 1. If description initiates the establishment of a new SCTP association, + as defined in [SCTP-SDP], Sections 10.3 and 10.4, set the value of connection's + [[sctpTransport]] internal slot to a newly created RTCSctpTransport. + + [TODO] + 2. If description negotiates the DTLS role of the SCTP transport, and there is an + RTCDataChannel with a null id, then generate an ID according to + [RTCWEB-DATA-PROTOCOL]. + + [Untestable] + If no available ID could be generated, then run the following steps: + + [Untestable] + 1. Let channel be the RTCDataChannel object for which an ID could not be + generated. + + [Untestable] + 2. Set channel's readyState attribute to closed. + + [Untestable] + 3. Fire an event named error with a ResourceInUse exception at channel. + + [Untestable] + 4. Fire a simple event named close at channel. + + [TODO] + 7. If description is set as a local description, then run the following steps for + each media description in description that is not yet associated with an + RTCRtpTransceiver object: + + [TODO] + 1. Let transceiver be the RTCRtpTransceiver used to create the media + description. + + [TODO] + 2. Set transceiver's mid value to the mid of the corresponding media + description. + + [TODO] + 8. If description is set as a remote description, then run the following steps + for each media description in description: + + [TODO] + 1. As described by [JSEP] (section 5.9.), attempt to find an existing + RTCRtpTransceiver object, transceiver, to represent the media description. + + [TODO] + 2. If no suitable transceiver is found (transceiver is unset), run the following + steps: + + [TODO] + 1. Create an RTCRtpSender, sender, from the media description. + + [TODO] + 2. Create an RTCRtpReceiver, receiver, from the media description. + + [TODO] + 3. Create an RTCRtpTransceiver with sender, receiver and direction, and let + transceiver be the result. + + [TODO] + 3. Set transceiver's mid value to the mid of the corresponding media description. + If the media description has no MID, and transceiver's mid is unset, generate + a random value as described in [JSEP] (section 5.9.). + + [TODO] + 4. If the direction of the media description is sendrecv or sendonly, and + transceiver.receiver.track has not yet been fired in a track event, process + the remote track for the media description, given transceiver. + + [TODO] + 5. If the media description is rejected, and transceiver is not already stopped, + stop the RTCRtpTransceiver transceiver. + + + [TODO] + 9. If description is of type "rollback", then run the following steps: + + [TODO] + 1. If the mid value of an RTCRtpTransceiver was set to a non-null value by + the RTCSessionDescription that is being rolled back, set the mid value + of that transceiver to null, as described by [JSEP] (section 4.1.8.2.). + + [TODO] + 2. If an RTCRtpTransceiver was created by applying the RTCSessionDescription + that is being rolled back, and a track has not been attached to it via + addTrack, remove that transceiver from connection's set of transceivers, + as described by [JSEP] (section 4.1.8.2.). + + [TODO] + 3. Restore the value of connection's [[SctpTransport]] internal slot to its + value at the last stable signaling state. + + [RTCPeerConnection-onnegotiationneeded] + 10. If connection's signaling state is now stable, update the negotiation-needed + flag. If connection's [[NegotiationNeeded]] slot was true both before and after + this update, queue a task that runs the following steps: + + [RTCPeerConnection-onnegotiationneeded] + 1. If connection's [[IsClosed]] slot is true, abort these steps. + + [RTCPeerConnection-onnegotiationneeded] + 2. If connection's [[NegotiationNeeded]] slot is false, abort these steps. + + [RTCPeerConnection-onnegotiationneeded] + 3. Fire a simple event named negotiationneeded at connection. + + [Trivial] + 11. Resolve p with undefined. + + [Trivial] + 3. Return p. + + +Coverage Report + + Tested 28 + Not Tested 22 + Untestable 8 + Total 58